package
{
	import de.polygonal.ds.HashMap;
	
	import flash.display.Sprite;
	import flash.events.Event;
	import flash.events.KeyboardEvent;
	import flash.events.MouseEvent;
	import flash.utils.getTimer;
	
	import srdk.SRKeyData;

	public class CGame extends Sprite
	{
		private static var m_KeyData :SRKeyData = new SRKeyData();

		private var m_mapGameState :HashMap;
		private var m_CurrentGameState :CGameState;
		
		private var m_nPrevTime :int;
		private var m_activate :Boolean = true;
		private var m_spriteDeactivateBlind :CDeactivateBlind = new CDeactivateBlind;
		
		public static function get KeyData() :SRKeyData { return m_KeyData; }
		
		public function CGame()
		{
			m_mapGameState = new HashMap();
			m_mapGameState.insert(CGameState.GAME_STATE_TITLE,		new CGameState_Title(this));
			m_mapGameState.insert(CGameState.GAME_STATE_EXPLAIN,	new CGameState_Explain(this));
			m_mapGameState.insert(CGameState.GAME_STATE_PLAY,		new CGameState_Play(this));
			m_mapGameState.insert(CGameState.GAME_STATE_RESULT,		new CGameState_Result(this));
			m_mapGameState.insert(CGameState.GAME_STATE_ENDING,		new CGameState_Ending(this));
			m_mapGameState.insert(CGameState.GAME_STATE_RANKING,	new CGameState_Ranking(this));
			
			m_CurrentGameState = null;
		}
		public function Init() :void
		{
			EnterState(CGameState.GAME_STATE_TITLE);
			//EnterState(CGameState.GAME_STATE_RANKING);
			
			stage.addEventListener(KeyboardEvent.KEY_UP, OnKeyUp);
			stage.addEventListener(KeyboardEvent.KEY_DOWN, OnKeyDown);
			stage.addEventListener(MouseEvent.MOUSE_DOWN, OnMouseDown);
			stage.addEventListener(MouseEvent.MOUSE_UP, OnMouseUp);
			
			m_nPrevTime = getTimer();
			stage.addEventListener(Event.ENTER_FRAME, RunGame);
			
			stage.addEventListener(Event.ACTIVATE, OnActivate);
			stage.addEventListener(Event.DEACTIVATE, OnDeactivate);
		}
		public function EnterState(nStateID :uint) :void
		{
			if (m_CurrentGameState != null)
			{
				m_CurrentGameState.LeaveState();
				this.removeChild(m_CurrentGameState.cMovieClip);
			}
			
			m_CurrentGameState = m_mapGameState.find(nStateID);
			
			this.addChild(m_CurrentGameState.cMovieClip);
			m_CurrentGameState.EnterState();
			stage.focus = stage;
		}
		
		private function RunGame(event :Event) :void
		{
			var nCurTime :int = getTimer();
			var nDeltaTime :int = nCurTime - m_nPrevTime;
			m_nPrevTime = nCurTime;
			var tick :Number = nDeltaTime * 0.001;
			
			if (m_activate == true)
				m_CurrentGameState.Run(tick);
		}
		
		private function OnKeyUp(event:KeyboardEvent):void
		{
			m_KeyData.OnKeyUp(event.keyCode);
		}
		private function OnKeyDown(event:KeyboardEvent):void
		{
			m_KeyData.OnKeyDown(event.keyCode);
		}
		private function OnMouseDown(event:MouseEvent):void
		{
			m_KeyData.OnMouseDown();
		}
		private function OnMouseUp(event:MouseEvent):void
		{
			m_KeyData.OnMouseUp();
		}
		
		private function OnActivate(event :Event) :void
		{
			if (m_activate == false)
			{
				stage.removeChild(m_spriteDeactivateBlind);
				CSoundManager.instance.SetAllVolume(1);	
			}
			m_activate = true;
		}
		private function OnDeactivate(event :Event) :void
		{
			if (m_activate == true)
			{
				stage.addChild(m_spriteDeactivateBlind);
				CSoundManager.instance.SetAllVolume(0);
			}
			m_activate = false;
		}
		
	}
}
